package com.util;


import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.io.FileInputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;


public class DecodeUtils {

	private static MessageDigest _hash;

	private static void initHash() {
		if (_hash != null)
			return;

		try {
			_hash = MessageDigest.getInstance("SHA-1");
		} catch (final NoSuchAlgorithmException e) {
			try {
				_hash = MessageDigest.getInstance("MD5");
			} catch (final NoSuchAlgorithmException e2) {
				final RuntimeException re = new RuntimeException(
						"No available hashing algorithm");
				re.initCause(e2);
				throw re;
			}
		}
	}

	public static String getHash(Object key) {
		initHash();

		final byte[] ba;
		synchronized (_hash) {
			_hash.update(key.toString().getBytes());
			ba = _hash.digest();
		}
		final BigInteger bi = new BigInteger(1, ba);
		final String result = bi.toString(16);
		if (result.length() % 2 != 0) {
			return "0" + result;
		}
		
		return result;
	}

	public static String getMD5(String val) {
		try {
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			md5.update(val.getBytes());

			byte[] bytes = md5.digest();// 加密
			
			String result = bytesToHexString(bytes);
			return result;
		} catch (NoSuchAlgorithmException ex) {
			return val;
		}
	}

	public static String bytesToHexString(byte[] bytes) {
		StringBuilder hex = new StringBuilder(bytes.length * 2);
		for(byte b : bytes) { 
			if ((b & 0xFF) < 0x10) 
				hex.append("0");
			hex.append(Integer.toHexString(b & 0xFF));
		} 
		return hex.toString();
	}
	
	public static byte[] hexStringToBytes(String hexString) {
		if (hexString.length() % 2 == 1)
			return null;
		byte[] ret = new byte[hexString.length() / 2];
		for (int i = 0; i < hexString.length(); i += 2) {
			ret[i / 2] = Integer.decode("0x" + hexString.substring(i, i + 2))
					.byteValue();
		}
		return ret;
	}
	
	public static String getMD5(File file) {
		if (!file.isFile()) {
			return null;
		}
		MessageDigest digest = null;
		FileInputStream in = null;
		byte buffer[] = new byte[1024];
		int len;
		try {
			digest = MessageDigest.getInstance("MD5");
			in = new FileInputStream(file);
			while ((len = in.read(buffer, 0, 1024)) != -1) {
				digest.update(buffer, 0, len);
			}
			in.close();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		String result = bytesToHexString(digest.digest());
		return result;
	}
	

	public static byte[] encrypt(String algorithm, String transformation, byte[] data, String key, byte[] iv) throws Exception {
		SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), algorithm);
		if(StringUtils.isEmpty(transformation)) {
			transformation = "";
		} else {
			transformation = "/" + transformation;
		}
		Cipher cipher = Cipher.getInstance(algorithm + transformation);
		
		if(iv != null) {
			IvParameterSpec zeroIv = new IvParameterSpec(iv);
			cipher.init(Cipher.ENCRYPT_MODE, keySpec, zeroIv);
		} else {
			cipher.init(Cipher.ENCRYPT_MODE, keySpec);
		}
		byte resultData[] = cipher.doFinal(data);
		
		//String result = Base64.encodeToString(decryptedData, Base64.DEFAULT);
		return resultData;
	}
	
	public static byte[] decrypt(String algorithm, String transformation, byte[] data, String key, byte[] iv) throws Exception {
		SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), algorithm);
		if(StringUtils.isEmpty(transformation)) {
			transformation = "";
		} else {
			transformation = "/" + transformation;
		}
		Cipher cipher = Cipher.getInstance(algorithm + transformation);
		if(iv != null) {
			IvParameterSpec zeroIv = new IvParameterSpec(iv);
			cipher.init(Cipher.DECRYPT_MODE, keySpec, zeroIv);
		} else {
			cipher.init(Cipher.DECRYPT_MODE, keySpec);
		}
		
		//byte[] byteMi = Base64.decode(data, Base64.DEFAULT);
		byte resultData[] = cipher.doFinal(data);
		
		//String result = new String(decryptedData);
		return resultData;
	}
	
	public static byte[] encrypt(String algorithm, byte[] data, String key, byte[] iv) throws Exception {
		String trans = iv == null? null: DecodeConst.TRANSFORMATION_CBC_P5;
		byte[] resultData = encrypt(algorithm, trans, data, key, iv);
		return resultData;
	}
	
	public static byte[] decrypt(String algorithm, byte[] data, String key, byte[] iv) throws Exception {
		String trans = iv == null? null: DecodeConst.TRANSFORMATION_CBC_P5;
		byte[] resultData = decrypt(algorithm, trans, data, key, iv);
		return resultData;
	}
	
	public static String encrypt_base64(String algorithm, String string, String key, byte[] iv) throws Exception {
		byte[] data = string.getBytes(DecodeConst.DOCODE_CODE);
		byte[] resultData = encrypt(algorithm, data, key, iv);
		String result = Base64.encodeBase64String(resultData);
		return result;
	}
	
	public static String decrypt_base64(String algorithm, String string, String key, byte[] iv) throws Exception {
		byte[] data = Base64.decodeBase64(string);
		byte[] resultData = decrypt(algorithm, data, key, iv);
		String result = new String(resultData, DecodeConst.DOCODE_CODE);
		return result;
	}
	
	public static String encrypt_hex(String algorithm, String string, String key, byte[] iv) throws Exception {
		byte[] data = string.getBytes();
		byte[] resultData = encrypt(algorithm, data, key, iv);
		String result = bytesToHexString(resultData);
		return result;
	}
	
	public static String decrypt_hex(String algorithm, String string, String key, byte[] iv) throws Exception {
		byte[] data = hexStringToBytes(string);
		byte[] resultData = decrypt(algorithm, data, key, iv);
		String result = new String(resultData);
		return result;
	}

	public static void main(String args[]) {

		try {
			String h1 = "[{WhsName=一般仓库, WhsCode=01}, {WhsName=原材料, WhsCode=101}, {WhsName=零件仓库, WhsCode=102}, {WhsName=电气仓库, WhsCode=103}, {WhsName=五金仓库, WhsCode=104}, {WhsName=半成品仓库, WhsCode=105}, {WhsName=成品仓库, WhsCode=106}, {WhsName=大件仓库, WhsCode=107}, {WhsName=辅料仓库, WhsCode=108}, {WhsName=车间仓库, WhsCode=109}, {WhsName=呆滞品仓库, WhsCode=110}, {WhsName=工量具仓库, WhsCode=111}, {WhsName=余料仓库, WhsCode=112}, {WhsName=库位仓库, WhsCode=113}]";

					String hh = DecodeUtils.encrypt_base64(DecodeConst.ALGORITHM_AES, h1, DecodeConst.WAP_AXIN_APP_KEY, DecodeConst.iv);
			System.out.println(""+hh);
//			String encrypt = DecodeUtils.encrypt_base64(DecodeConst.ALGORITHM_AES, h1, DecodeConst.WAP_AXIN_APP_KEY, DecodeConst.iv);
//			System.out.println(""+encrypt);

			String hhh = "d2XQLTHxOU1QMBWX1sCDalSVOJS5dhNhadMS/3CKXV7+WtHCOvumrr7VGDL/nwK5mNrL20+z4cSH2I/GpElVhXSkv3/jDnOVOvG/svgcqTPIWo9BFJsmMr8tGx4b8O8xIuaEXESWJPZM7U7odNspZKWMsMeI7uuZQjfdkEhcSeJBJADXSjgvNbXGAD6goS6Jv8HXRuzv24EL4rmGQ+Y0vX3NvfXymJeO4S8/GpOWgpTOZw8OhMnKW2zyuHJS0I6HE8fKoZCa1GqGFwx5wLRaJjJLH6uwPO96A8jyZr7qjx082MMy2YZ4lrcuQpM7eurA4RrYl1mh3Uc9sxH/lwJYhx+j58ofHlxcIVfFGAywQ9BGQwce6AXsOTSqKUphoAi6Xpor3/Mspm6VqRJZQmmgB6kBuFD7MVZDT2tcTVMK5p700JXOPcX1FEcuOlqlyRCb10Ue+Msx/RRyazxFWaq1/Yk0ccnvYKg919exnNFixljt0OzMw2iZvyqj8ZMwyB1JI91bE1Z5BHwiBoMYo8EzjnI9gmaqiYHTXdI/4AEsetUCTzPoXDsbqPdwJvFMdBu2Foo36CLoC9on/iP3d8t3sjX6HarAWDHK5LZvsAjsEGjlAVmzUYHZWbHlGtn4cEnDxv32vkxGuUq4a9N/7SsSYkB9e2yFbZIHyHFfyquhfrP2stpXLqPKuJGq2ZHUI5hkyn3Utor0iwu82ok67vOWKUaq1GpMOYvwj6iMqqlsNXES393GIYqiIfcfi06cUov4S1sSCJWP2giZR6oYoCtPuSn6yUev7IYz5jTKqVs3MklFtpWZI5+iPRCzCH+c7aO9eRRdFU8Dy8mC8Ni7kzRg+uOhqhUQoCHWIEdUlA/T0zWNA3y704z0dpozIaSzuBTGrQaQJhDl0L/mhN+fAPPbn4v9CZ0crzxCuCTW44JMgGLVXifqrQwaivANdk/ONRvYG3WAYIUXdiBsoni3GwGTz38m2rkuV0P1pJtwnInKba+74GNL82d1UCP6V4mWKHYXCLbZOW6CxbEy7aw/TCoKKfNrgc4rsoaqVoqhHHpbGY2RAdhEf8wuL6nq+rdawdNpe9r7rNkh+JU3ghnqtfqeU7XusJriYfXb4qoF+GvmzGOdiAyayXBKOXlhpW1kuZ/KUIwhuFi/qxL+QdHHoDYD7tQ6pD65MQZe0PxcpaEQ626w6DoI+3x845I6tAYk43iUHZPMrNeKqfjO+dx+NVJ2RPy2DSDk2CNCROIGyqipyP58+SaLeIQocBpgFSUxHZORqquitdstBkthCV+/cbeNFiY7hQ2gf2UfvfXWsiIEd00=";
			String ss = DecodeUtils.decrypt_base64(DecodeConst.ALGORITHM_AES, hhh, DecodeConst.WAP_AXIN_APP_KEY, DecodeConst.iv);

			System.out.println(""+ss);
		}catch (Exception e){
			System.out.print(e);
		}

//		System.out.println(DecodeUtils.encrypt_base64());
	}
}
